package com.summer.data.apt;

import com.sun.tools.javac.api.JavacTrees;
import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.tree.JCTree.JCClassDecl;
import com.sun.tools.javac.tree.TreeMaker;
import com.sun.tools.javac.tree.TreeTranslator;
import com.sun.tools.javac.util.List;
import com.sun.tools.javac.util.Name;
import com.sun.tools.javac.util.Names;

import javax.annotation.processing.Messager;
import javax.lang.model.element.Element;

import static com.summer.data.apt.Constant.COLUMN_DATA_MAP;

/**
 * @author ydfqy
 */
public class TreeHelper {

    protected Messager messager;
    protected JavacTrees trees;
    protected TreeMaker treeMaker;
    protected Names names;


    public TreeHelper(Messager messager, JavacTrees trees, TreeMaker treeMaker, Names names) {
        this.messager = messager;
        this.trees = trees;
        this.treeMaker = treeMaker;
        this.names = names;
    }


    public JCTree.JCExpression typeRef(Class clazz) {
        String className = clazz.getName().replace("$", ".");
        return typeRef(className);
    }

    public JCTree.JCExpression typeRef(String complexName) {
//        System.out.println("complexName:" + complexName);
        String[] parts = complexName.split("\\.");
        if (parts.length > 2 && parts[0].equals("java") && parts[1].equals("lang")) {
            String[] subParts = new String[parts.length - 2];
            System.arraycopy(parts, 2, subParts, 0, subParts.length);
            return javaLangTypeRef(subParts);
        }

        return chainDots(parts);
    }

    public JCTree.JCExpression javaLangTypeRef(String... simpleNames) {
        for (String simpleName : simpleNames) {
            System.out.println("simpleName:" + simpleName);
        }
        return chainDots(null, null, simpleNames);
    }

    public JCTree.JCExpression chainDots(String elem1, String elem2, String... elems) {
        return chainDots(-1, elem1, elem2, elems);
    }

    public JCTree.JCExpression chainDots(String... elems) {
        assert elems != null;

        JCTree.JCExpression e = null;
        for (String elem : elems) {
            if (e == null) {
                e = treeMaker.Ident(toName(elem));
            } else {
                e = treeMaker.Select(e, toName(elem));
            }
        }
        return e;
    }

    public JCTree.JCExpression chainDots(int pos, String elem1, String elem2, String... elems) {
        assert elems != null;
//        TreeMaker treeMaker = getTreeMaker();
        if (pos != -1) {
            treeMaker = treeMaker.at(pos);
        }
        JCTree.JCExpression e = null;
        if (elem1 != null) {
            e = treeMaker.Ident(toName(elem1));
        }
        if (elem2 != null) {
            e = e == null ? treeMaker.Ident(toName(elem2)) : treeMaker.Select(e, toName(elem2));
        }
        for (int i = 0; i < elems.length; i++) {
            e = e == null ? treeMaker.Ident(toName(elems[i])) : treeMaker.Select(e, toName(elems[i]));
        }

        assert e != null;

        return e;
    }

    public Name toName(String name) {
        return this.names.fromString(name);
    }

    public JCClassDecl classDef(long modifiers, String className) {
        return treeMaker.ClassDef(
            treeMaker.Modifiers(modifiers),
            toName(className),                      // 类名
            List.nil(),                             // 泛型参数列表
            null,                                   // 基类
            List.nil(),                             // 实现的接口
            List.nil()                              // 类定义的详细语句，包括字段、方法的定义等等
        );
    }

    public JCClassDecl classDef(long modifiers, String className, String baseClassName) {
        return treeMaker.ClassDef(
            treeMaker.Modifiers(modifiers),
            toName(className),                      // 类名
            List.nil(),                             // 泛型参数列表
            typeRef(baseClassName),                 // 基类
            List.nil(),                             // 实现的接口
            List.nil()                              // 类定义的详细语句，包括字段、方法的定义等等
        );
    }

    public void varDef(long modifiers, String varName, String varType, JCTree.JCExpression initVal) {
        treeMaker.VarDef(
            treeMaker.Modifiers(modifiers),
            toName(varName),
            typeRef(varType),
            initVal
        );
    }

    public JCTree.JCExpression column2DataType(JCTree.JCVariableDecl varDecl) {
        String columnType = varDecl.vartype.type.toString();
        String dataType = COLUMN_DATA_MAP.get(columnType);
        return typeRef(dataType);
    }

}
